﻿using System;
using System.Collections.Generic;
using System.Drawing;
using Oscilloscope.Adjust;
using Oscilloscope.Channel;
using Oscilloscope.ChannelBuffer;
using Oscilloscope.Util;

namespace Oscilloscope.Curve
{
	// Token: 0x02000008 RID: 8
	internal class MultipleDigitalCurveGenerator : ICurveGenerator, IDisposable
	{
		// Token: 0x06000028 RID: 40 RVA: 0x000035DC File Offset: 0x000017DC
		public MultipleDigitalCurveGenerator(IChannel channel)
		{
			if (channel == null)
			{
				throw new ArgumentNullException();
			}
			this.curves = new Curve[16];
			this.pointCountLessThanBufferCapcityCounts = new int[16];
			this.curveCountLessThanBufferCapcityCounts = new int[16];
			for (int i = 0; i < 16; i++)
			{
				this.curves[i] = new Curve(null, 0, null);
				this.pointCountLessThanBufferCapcityCounts[i] = 0;
				this.curveCountLessThanBufferCapcityCounts[i] = 0;
			}
			this.channel = channel;
			this.dataBufferIterator = ChannelBufferDataIteratorFactory.ChannelDataBufferIterator(this.channel.GetChannelBuffer().GetSignalType());
		}

		// Token: 0x06000029 RID: 41 RVA: 0x00003670 File Offset: 0x00001870
		public Curve[] GetCurves()
		{
			Curve[] array = new Curve[16];
			for (int i = 0; i < 16; i++)
			{
				if ((this.channel.GetBitMask() >> i & 1) == 1)
				{
					array[i] = this.curves[i];
				}
			}
			return array;
		}

		// Token: 0x0600002A RID: 42 RVA: 0x000036B4 File Offset: 0x000018B4
		public void PrepareCurve(ChannelBufferData[] dataBuffer, int dataBufferValidCount, double dataBufferStartTime)
		{

            for (int i = 0; i < 16; i++)
			{
				this.PrepareCurve(dataBuffer, dataBufferValidCount, dataBufferStartTime, i);
			}
		}

		// Token: 0x0600002B RID: 43 RVA: 0x000036D8 File Offset: 0x000018D8
		private void PrepareCurve(ChannelBufferData[] dataBuffer, int dataBufferValidCount, double dataBufferStartTime, int bitIndex)
		{

       
            int width = this.channel.GetCanvasSize().Width;
			int height = this.channel.GetCanvasSize().Height;
			if (width <= 0 || height <= 0)
			{
				this.curves[bitIndex].CurveSegmentCount = 0;
				return;
			}
			float num = (float)this.channel.GetCanvasSize().Height / 16f;
			float num2 = (float)this.channel.GetCanvasSize().Height / 20f;
			float num3 = (float)(bitIndex + 1) * num;
			double num4;
			double num5;
			this.channel.GetTimeSpan(out num4, out num5);
			double num6 = TimePerCellAdjustGrade.Instance.GetValueOfGrade(this.channel.GetTimePerCellGrade()) * 10.0;
			double num7 = 0.0;
			double num8 = 0.0;
			double num9 = 0.0;
			double num10 = 0.0;
			int num11 = 0;
			this.EnsureCurveBufferCapcity(num11, bitIndex);
			int num12 = 0;
			int num13 = 0;
			PointF[] array = new PointF[2];
			this.dataBufferIterator.Initialize(dataBuffer, dataBufferValidCount, dataBufferStartTime, this.channel.GetChannelBuffer().GetTimeInterval(), bitIndex);
            

            while (this.dataBufferIterator.Next(ref num7, ref num8))
			{
				float num14 = (float)((double)width * ((num8 - num4) / num6));
				float num15 = (float)((double)num3 - (double)num2 * num7);
				if (num14 >= 0f && num14 <= (float)width && num15 >= 0f && num15 <= (float)height)
				{
					PointF[] array2 = this.dataBufferIterator.SetNewPoint(num14, num15);
					if (array2 != null)
					{
						foreach (PointF pointF in array2)
						{
							this.EnsurePointBufferCapcity(num13 + num12, bitIndex);
							this.curves[bitIndex].CurvePoints[num13 + num12].X = pointF.X;
							this.curves[bitIndex].CurvePoints[num13 + num12].Y = pointF.Y;
							num12++;
						}
					}
					
				}
				else
				{
					PointF[] point = this.dataBufferIterator.GetPoint();
					if (point != null)
					{
						foreach (PointF pointF2 in point)
						{
							this.EnsurePointBufferCapcity(num13 + num12, bitIndex);
							this.curves[bitIndex].CurvePoints[num13 + num12].X = pointF2.X;
							this.curves[bitIndex].CurvePoints[num13 + num12].Y = pointF2.Y;
							num12++;
						}
					}
					if (num12 > 0)
					{
						int num16 = InternalUtils.InterpolationWithCanvas(new PointF(this.curves[bitIndex].CurvePoints[num13 + num12 - 1].X, this.curves[bitIndex].CurvePoints[num13 + num12 - 1].Y), new PointF(num14, num15), width, height, array);
						for (int k = 0; k < num16; k++)
						{
							this.EnsurePointBufferCapcity(num13 + num12, bitIndex);
							this.curves[bitIndex].CurvePoints[num13 + num12].X = array[k].X;
							this.curves[bitIndex].CurvePoints[num13 + num12].Y = array[k].Y;
							num12++;
						}
						this.curves[bitIndex].CurveSegments[num11].StartIndex = num13;
						this.curves[bitIndex].CurveSegments[num11].PointCount = num12;
						num11++;
						this.EnsureCurveBufferCapcity(num11, bitIndex);
						num13 += num12;
						num12 = 0;
					}
					else
					{
						bool flag = this.dataBufferIterator.PeekNext(ref num9, ref num10);
						if (flag)
						{
							float x = (float)((double)width * ((num10 - num4) / num6));
							float y = (float)((double)num3 - (double)num2 * num9);
							int num16 = InternalUtils.InterpolationWithCanvas(new PointF(num14, num15), new PointF(x, y), width, height, array);
							if (num12 > 0)
							{
								for (int l = 0; l < num16; l++)
								{
									this.EnsurePointBufferCapcity(num13 + num12, bitIndex);
									this.curves[bitIndex].CurvePoints[num13 + num12].X = array[l].X;
									this.curves[bitIndex].CurvePoints[num13 + num12].Y = array[l].Y;
									num12++;
								}
								if (num16 > 0)
								{
									this.curves[bitIndex].CurveSegments[num11].StartIndex = num13;
									this.curves[bitIndex].CurveSegments[num11].PointCount = num12;
									num11++;
									this.EnsureCurveBufferCapcity(num11, bitIndex);
									num13 += num12;
									num12 = 0;
								}
							}
							else
							{
								for (int m = 0; m < num16; m++)
								{
									this.EnsurePointBufferCapcity(num13 + num12, bitIndex);
									this.curves[bitIndex].CurvePoints[num13 + num12].X = array[m].X;
									this.curves[bitIndex].CurvePoints[num13 + num12].Y = array[m].Y;
									num12++;
								}
								if (num16 >= 2)
								{
									this.curves[bitIndex].CurveSegments[num11].StartIndex = num13;
									this.curves[bitIndex].CurveSegments[num11].PointCount = num12;
									num11++;
									this.EnsureCurveBufferCapcity(num11, bitIndex);
									num13 += num12;
									num12 = 0;
								}
							}
						}
					}
				}
			}
			PointF[] point2 = this.dataBufferIterator.GetPoint();
			if (point2 != null)
			{
				foreach (PointF pointF3 in point2)
				{
					this.EnsurePointBufferCapcity(num13 + num12, bitIndex);
					this.curves[bitIndex].CurvePoints[num13 + num12].X = pointF3.X;
					this.curves[bitIndex].CurvePoints[num13 + num12].Y = pointF3.Y;
					num12++;
				}
			}
			if (num12 > 0)
			{
				this.curves[bitIndex].CurveSegments[num11].StartIndex = num13;
				this.curves[bitIndex].CurveSegments[num11].PointCount = num12;
				num11++;
				num13 += num12;
				num12 = 0;
			}
			this.curves[bitIndex].CurveSegmentCount = num11;
			this.PreviousCurveCount(num11, bitIndex);
			this.PreviousPointCount(num13 + num12, bitIndex);
		}

		// Token: 0x0600002C RID: 44 RVA: 0x00003DF0 File Offset: 0x00001FF0
		public CurveVerPosIndicator[] GetCurveVerPosIndicators()
		{
			CurveVerPosIndicator[] array = new CurveVerPosIndicator[16];
			float num = (float)this.channel.GetCanvasSize().Height / 16f;
			float num2 = (float)this.channel.GetCanvasSize().Height / 20f;
			for (int i = 0; i < array.Length; i++)
			{
				if ((this.channel.GetBitMask() >> i & 1) != 0)
				{
					array[i] = new CurveVerPosIndicator((float)(i + 1) * num, string.Format("{0}.{1}", this.channel.GetChannelSN().ToString(), i.ToString()));
				}
			}
			return array;
		}

		// Token: 0x0600002D RID: 45 RVA: 0x00003E92 File Offset: 0x00002092
		public void Dispose()
		{
			this.curves = null;
			this.channel = null;
			GC.Collect();
		}

		// Token: 0x0600002E RID: 46 RVA: 0x00003EA8 File Offset: 0x000020A8
		protected void EnsureCurveBufferCapcity(int curveIndex, int bitIndex)
		{
			if (this.curves[bitIndex].CurveSegments == null)
			{
				this.curves[bitIndex].CurveSegments = new CurveSegment[MultipleDigitalCurveGenerator.CURVE_BUFFER_INC_STEP];
			}
			int num = this.curves[bitIndex].CurveSegments.Length;
			while (curveIndex >= num)
			{
				num += MultipleDigitalCurveGenerator.CURVE_BUFFER_INC_STEP;
			}
			if (num != this.curves[bitIndex].CurveSegments.Length)
			{
				CurveSegment[] curveSegments = this.curves[bitIndex].CurveSegments;
				this.curves[bitIndex].CurveSegments = new CurveSegment[num];
				Array.Copy(curveSegments, this.curves[bitIndex].CurveSegments, curveSegments.Length);
				this.curveCountLessThanBufferCapcityCounts[bitIndex] = 0;
			}
		}

		// Token: 0x0600002F RID: 47 RVA: 0x00003F4C File Offset: 0x0000214C
		protected void EnsurePointBufferCapcity(int pointIndex, int bitIndex)
		{
			if (this.curves[bitIndex].CurvePoints == null)
			{
				this.curves[bitIndex].CurvePoints = new PointF[MultipleDigitalCurveGenerator.POINT_BUFFER_INC_STEP];
			}
			int num = this.curves[bitIndex].CurvePoints.Length;
			while (pointIndex >= num)
			{
				num += MultipleDigitalCurveGenerator.POINT_BUFFER_INC_STEP;
			}
			if (num != this.curves[bitIndex].CurvePoints.Length)
			{
				PointF[] curvePoints = this.curves[bitIndex].CurvePoints;
				this.curves[bitIndex].CurvePoints = new PointF[num];
				Array.Copy(curvePoints, this.curves[bitIndex].CurvePoints, curvePoints.Length);
				this.pointCountLessThanBufferCapcityCounts[bitIndex] = 0;
			}
		}

		// Token: 0x06000030 RID: 48 RVA: 0x00003FF0 File Offset: 0x000021F0
		protected void PreviousCurveCount(int previousCurveCount, int bitIndex)
		{
			if (this.curves[bitIndex].CurveSegments == null)
			{
				return;
			}
			if (this.curves[bitIndex].CurveSegments.Length - MultipleDigitalCurveGenerator.CURVE_BUFFER_DEC_STEP > previousCurveCount)
			{
				this.curveCountLessThanBufferCapcityCounts[bitIndex]++;
			}
			if (this.curveCountLessThanBufferCapcityCounts[bitIndex] >= MultipleDigitalCurveGenerator.BUFFER_SIZE_ADJUST_THRESHOLD)
			{
				CurveSegment[] curveSegments = this.curves[bitIndex].CurveSegments;
				if (curveSegments.Length - MultipleDigitalCurveGenerator.CURVE_BUFFER_DEC_STEP >= 0)
				{
					this.curves[bitIndex].CurveSegments = new CurveSegment[curveSegments.Length - MultipleDigitalCurveGenerator.CURVE_BUFFER_DEC_STEP];
					Array.Copy(curveSegments, this.curves[bitIndex].CurveSegments, curveSegments.Length - MultipleDigitalCurveGenerator.CURVE_BUFFER_DEC_STEP);
				}
				this.curveCountLessThanBufferCapcityCounts[bitIndex] = 0;
				GC.Collect();
			}
		}

		// Token: 0x06000031 RID: 49 RVA: 0x000040AC File Offset: 0x000022AC
		protected void PreviousPointCount(int previousPointCount, int bitIndex)
		{
			if (this.curves[bitIndex].CurvePoints == null)
			{
				return;
			}
			if (this.curves[bitIndex].CurvePoints.Length - MultipleDigitalCurveGenerator.POINT_BUFFER_DEC_STEP > previousPointCount)
			{
				this.pointCountLessThanBufferCapcityCounts[bitIndex]++;
			}
			if (this.pointCountLessThanBufferCapcityCounts[bitIndex] >= MultipleDigitalCurveGenerator.BUFFER_SIZE_ADJUST_THRESHOLD)
			{
				PointF[] curvePoints = this.curves[bitIndex].CurvePoints;
				this.curves[bitIndex].CurvePoints = new PointF[curvePoints.Length - MultipleDigitalCurveGenerator.POINT_BUFFER_DEC_STEP];
				Array.Copy(curvePoints, this.curves[bitIndex].CurvePoints, curvePoints.Length - MultipleDigitalCurveGenerator.POINT_BUFFER_DEC_STEP);
				this.pointCountLessThanBufferCapcityCounts[bitIndex] = 0;
				GC.Collect();
			}
		}

		// Token: 0x04000005 RID: 5
		private static readonly int CURVE_BUFFER_INC_STEP = 500;

		// Token: 0x04000006 RID: 6
		private static readonly int CURVE_BUFFER_DEC_STEP = 100;

		// Token: 0x04000007 RID: 7
		private static readonly int POINT_BUFFER_INC_STEP = 5000;

		// Token: 0x04000008 RID: 8
		private static readonly int POINT_BUFFER_DEC_STEP = 1000;

		// Token: 0x04000009 RID: 9
		private static readonly int BUFFER_SIZE_ADJUST_THRESHOLD = 32;

		// Token: 0x0400000A RID: 10
		private int[] pointCountLessThanBufferCapcityCounts;

		// Token: 0x0400000B RID: 11
		private int[] curveCountLessThanBufferCapcityCounts;

		// Token: 0x0400000C RID: 12
		private Curve[] curves;

		// Token: 0x0400000D RID: 13
		private IChannel channel;

		// Token: 0x0400000E RID: 14
		private IChannelBufferDataIterator dataBufferIterator;

        List<double> dSingle = new List<double>();
        public List<double> doublesSingle { get => dSingle; }
    }
}
